home *** CD-ROM | disk | FTP | other *** search
- /**************************************************************************
- * *
- * Copyright (c) 1991 Silicon Graphics, Inc. *
- * All Rights Reserved *
- * *
- * THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF SGI *
- * *
- * The copyright notice above does not evidence any actual of intended *
- * publication of such source code, and is an unpublished work by Silicon *
- * Graphics, Inc. This material contains CONFIDENTIAL INFORMATION that is *
- * the property of Silicon Graphics, Inc. Any use, duplication or *
- * disclosure not specifically authorized by Silicon Graphics is strictly *
- * prohibited. *
- * *
- * RESTRICTED RIGHTS LEGEND: *
- * *
- * Use, duplication or disclosure by the Government is subject to *
- * restrictions as set forth in subdivision (c)(1)(ii) of the Rights in *
- * Technical Data and Computer Software clause at DFARS 52.227-7013, *
- * and/or in similar or successor clauses in the FAR, DOD or NASA FAR *
- * Supplement. Unpublished - rights reserved under the Copyright Laws of *
- * the United States. Contractor is SILICON GRAPHICS, INC., 2011 N. *
- * Shoreline Blvd., Mountain View, CA 94039-7311 *
- **************************************************************************
- *
- * File: SLMain.c
- *
- * Description: This file contains all public function definitions for
- * libspool, the printer spooler API library. The public functions
- * either perform the required processing directly, call local
- * functions in this file or call spooling system specific functions
- * in the the spooling files (eg. SLBsd.c, or SLSsysV.c).
- *
- **************************************************************************/
-
-
- #ident "$Revision: 1.3 $"
-
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <time.h>
- #include <ctype.h>
- #include <bstring.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <netinet/in.h>
- #include <sys/un.h>
- #ifdef _SL_FASTPATH
- #include <fastprint.h>
- #endif /* _SL_FASTPATH */
- #include "spoolI.h"
-
-
- /* Possible spooling systems */
-
- static SLSpoolerStruct pos_spooler_list[] = {
- { SL_SPOOLER_BSD,
- _SLBsdFindSpooler,
- _SLBsdGetPrinterList,
- _SLBsdGetPrinterInfo,
- _SLBsdGetDefPrinterName,
- _SLBsdGetPrinterSettings,
- _SLBsdSubmitJob,
- _SLBsdCancelJob,
- _SLBsdGetSpoolerState,
- _SLBsdSetSpoolerState,
- _SLBsdGetQueue,
- #ifdef _SL_FASTPATH
- _SLBsdSupportsFastJob,
- #endif /* _SL_FASTPATH */
- _SLBsdFindUserName,
- },
- { SL_SPOOLER_SYSV,
- _SLSysVFindSpooler,
- _SLSysVGetPrinterList,
- _SLSysVGetPrinterInfo,
- _SLSysVGetDefPrinterName,
- _SLSysVGetPrinterSettings,
- _SLSysVSubmitJob,
- _SLSysVCancelJob,
- _SLSysVGetSpoolerState,
- _SLSysVSetSpoolerState,
- _SLSysVGetQueue,
- #ifdef _SL_FASTPATH
- _SLSysVSupportsFastJob,
- #endif /* _SL_FASTPATH */
- _SLSysVFindUserName,
- },
- { 0, NULL },
- };
-
-
- /* Global variables */
-
- int SLdebug; /* Run-time debugging info provided if != 0 */
- long SLnet_timeout = SL_NET_TIMEOUT; /* Timeout for network ops. (sec.) */
-
-
- /* Local variables */
-
- static SLSpoolerStruct *def_sptr; /* Pointer to the def spooler */
- static uint def_spooler = SL_SPOOLER_NONE; /* Default spooler */
- static uint avail_spoolers = SL_SPOOLER_NONE; /* Available spoolers */
- static SLPrintJob print_job; /* Print job info */
-
-
- /* Local functions */
-
- static int find_spoolers(unsigned int*);
- static void init_job(SLPrintJob*);
- static SLPrintJob* submit_job(SLJobSourceUnion*, const char*, int, int,
- int, const char*, const char*);
- static void sort_plist(SLPrinterStruct*, int);
-
-
- /**************************************************************************
- *
- * Function: SLGetSpooler
- *
- * Description: Returns the default spooling system for the library. If
- * the default is SL_SPOOLER_NONE, an attempt is made to determine
- * if either the SYS V lpsched or BSD lpd daemons are running.
- *
- * Parameters:
- * defaultp (O) - default spooler (one of SL_SPOOLER_NONE,
- * SL_SPOOLER_BSD or SL_SPOOLER_SYSV)
- * availablep (O) - Bit mask of available spooling systems.
- *
- * Return: 0 indicates successful execution. -1 indicates execution error,
- * SLerrno is set.
- *
- **************************************************************************/
-
- int SLGetSpooler(unsigned int *defaultp, unsigned int *availablep)
- {
- register SLSpoolerStruct *sptr;
-
- /*
- * If appears no spoolers are available make sure before
- * reporting it
- */
- if (avail_spoolers == SL_SPOOLER_NONE) {
- if (find_spoolers(&avail_spoolers) < 0)
- RETURN_ERROR(SL_ERR_FIND_SPOOLER)
- }
- *availablep = avail_spoolers;
-
- /*
- * If a spooler other than NONE is selected return that.
- * Otherwise look in available spooler list and set def spooler
- * from first available one in list.
- */
- if (def_spooler == SL_SPOOLER_NONE) {
- /*
- * Try to set the prefered spooler first
- */
- *defaultp = SL_SPOOLER_NONE;
- if (avail_spoolers & SL_SPOOLER_PREF) {
- *defaultp = SL_SPOOLER_PREF;
- for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
- if (SL_SPOOLER_PREF == sptr->mask) {
- def_sptr = sptr;
- break;
- }
- }
- } else {
- for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
- if (avail_spoolers & sptr->mask) {
- *defaultp = sptr->mask;
- def_sptr = sptr;
- break;
- }
- }
- }
- } else {
- *defaultp = def_spooler;
- }
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSetSpooler
- *
- * Description: Sets the default spooling system for future libspool
- * functions.
- *
- * Parameters:
- * spooler (I) - spooling system to make default (eg. SL_SPOOLER_BSD).
- *
- * Return: 0 is returned if execution is successful. If an error has
- * occurred, -1 is returned and SLerrno is set. Note that it is
- * considered an error to request a spooling system that is not
- * available. It is also an error to specify SL_SPOOLER_NONE.
- *
- **************************************************************************/
-
- int SLSetSpooler(unsigned int spooler)
- {
- register SLSpoolerStruct *sptr;
-
- /*
- * Make sure a spooler has been specified
- */
- if (spooler == SL_SPOOLER_NONE)
- RETURN_ERROR(SL_ERR_SPOOLER_NONE);
-
- /*
- * If appears no spoolers are available make sure before
- * reporting an error.
- */
- if (avail_spoolers == SL_SPOOLER_NONE) {
- if (find_spoolers(&avail_spoolers) < 0)
- RETURN_ERROR(SL_ERR_FIND_SPOOLER);
- if (avail_spoolers == SL_SPOOLER_NONE)
- RETURN_ERROR(SL_ERR_NO_SPOOLERS);
- }
-
- /*
- * Make sure specified spooler is in list of available spoolers
- * and if so set the default spooler to the specified spooler.
- */
- if (spooler & avail_spoolers) {
- for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
- if (spooler & sptr->mask) {
- def_spooler = spooler;
- def_sptr = sptr;
- break;
- }
- }
- } else
- RETURN_ERROR(SL_ERR_SPOOLER_UNKNOWN);
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLGetPrinterList
- *
- * Description: Provides a list of the printers recognized by the
- * currently selected spooling system. Each time this function
- * is called the old list pointer, if any, obtained from a
- * previous call to this function becomes invalid. If the user
- * wishes to preserve the old list, a copy must be made before
- * calling this function.
- *
- * Parameters:
- * printersp (O) - set to a list of available printers. If there
- * are no printers registered with the spooler,
- * this variable will be set to NULL.
- * num_printersp (O) - number of available printers in list. If there
- * are no printers available this value will be
- * 0.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred.
- *
- **************************************************************************/
-
- int SLGetPrinterList(SLPrinterStruct *printersp[], int *num_printersp)
- {
- /*
- * In case no spooler make sure sane values are sent back
- */
- *printersp = NULL;
- *num_printersp = 0;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->get_printers_func(printersp, num_printersp) < 0)
- return SL_ERROR;
-
- /*
- * Sort the printer list by local name
- */
- sort_plist(*printersp, *num_printersp);
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLGetPrinterInfo
- *
- * Description: Provides detailed information about the specified printer.
- * Each time this function is called the old contents of the internal
- * info structure become invalid. If the user wishes to preserve the
- * old info, a copy must be made before calling this function.
- *
- * Parameters:
- * printer (I) - printer whose info is wanted. If NULL,
- * the default printer is used.
- * printer_infop (O) - set to a printer information structure
- * filled with information about the printer. Set
- * to NULL if the specified printer does not exist.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred. It is considered an error specifying a printer
- * that is not available to the spooler.
- *
- **************************************************************************/
-
- int SLGetPrinterInfo(const char *printer, SLPrinterStruct **printer_infop)
- {
- char *def_printer;
-
- /*
- * In case of error make sure sane values are sent back
- */
- *printer_infop = NULL;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Get the default printer name if no printer specified.
- * Also sanity check the printer name, if specified.
- */
- if (!printer) {
- if (SLGetDefPrinterName(&def_printer) < 0)
- return SL_ERROR;
- printer = def_printer;
- } else if (_SLIsEmpty(printer))
- RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->get_printer_info_func(printer, printer_infop) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLGetDefPrinterName
- *
- * Description: Returns the name of the default printer for the currently
- * selected spooliong system.
- *
- * Parameters:
- * pnamep (O) - set to the name of the default printer or to
- * NULL if no printer is registered as the default.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred.
- *
- **************************************************************************/
-
- int SLGetDefPrinterName(char **pnamep)
- {
- /*
- * In case no spooler make sure sane values are sent back
- */
- *pnamep = NULL;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->get_def_printer_func(pnamep) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLGetPrinterSettings
- *
- * Description: Reads the spooler and printer option settings that have
- * been saved by the SL settings save functions (e.g.
- * SLSysVSaveSpoolerOptions and SLSysVSavePrinterOptions).
- * The settings are returned in a spooling system independ format.
- * Each time this function is called the old contents of the internal
- * settings structure becomes invalid. If the caller wishes to
- * preserve the old settings information, a copy must be made before
- * calling this function.
- *
- * Note that calling this function does not effect the contents of
- * the settings files stored on disk. If settings files for the
- * specified printer are not found, default settings appropriate to
- * the default behavior of the current spooler are returned.
- *
- * Parameters:
- * printer (I) - printer whose settings are wanted. If NULL,
- * the default printer is used. If the printer
- * specified does not exist, the default settings
- * for the current spooler will be returned.
- * settingsp (O) - set to a printer settings structure
- * filled with the currently saved spooler
- * and printer option settings.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred.
- *
- **************************************************************************/
-
- int SLGetPrinterSettings(const char *printer, SLSettingsStruct **settingsp)
- {
- char *def_printer;
-
- /*
- * In case of error make sure sane values are sent back
- */
- *settingsp = NULL;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Get the default printer name if no printer specified.
- * Also sanity check the printer name, if specified.
- */
- if (!printer) {
- if (SLGetDefPrinterName(&def_printer) < 0)
- return SL_ERROR;
- printer = def_printer;
- } else if (_SLIsEmpty(printer))
- RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->get_printer_settings_func(printer, settingsp) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSysVGetSpoolerOptions
- *
- * Description: Reads the spooler option settings that have
- * been saved by SLSysVSaveSpoolerOptions. The options are
- * returned in a format consistent with the System V spooling system.
- * Each time this function is called the old contents of the internal
- * settings structure becomes invalid. If the caller wishes to
- * preserve the old settings information, a copy must be made before
- * calling this function.
- *
- * Note that calling this function does not effect the contents of
- * the settings files stored on disk. If a spooler option file is
- * not found for the calling user, default settings are returned.
- *
- * Parameters:
- * spooler_optsp (O) - set to a spooler options structure
- * filled with the currently saved spooler options
- * or default values if no spooler options file
- * is found.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred. It is considered an error to call this function
- * if the System V spooler is not the currently set spooling system.
- *
- **************************************************************************/
-
- int SLSysVGetSpoolerOptions(SLSysVSpoolerOptionsStruct **spooler_optsp)
- {
- /*
- * In case of error make sure sane values are sent back
- */
- *spooler_optsp = NULL;
-
- /*
- * Make sure we have the System V spooler set otherwise
- * we return an error indication.
- */
- CHECK_DEF_SPOOLER;
- if (def_sptr->mask != SL_SPOOLER_SYSV)
- RETURN_ERROR(SL_ERR_NO_SYSV);
-
- /*
- * Call the appropriate function
- */
- if (_SLSysVGetSpoolerOptions(spooler_optsp) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSysVGetPrinterOptions
- *
- * Description: Reads the printer specific option settings that have
- * been saved by SLSysVSavePrinterOptions. The printer options
- * consists of a string of printer specific options that would
- * typically be specified on the lp command line using the "-o"
- * switch. Each time this function is called the old contents of
- * the internal string storage becomes invalid. If the caller wishes to
- * preserve the old information, a copy must be made before
- * calling this function.
- *
- * Note that calling this function does not effect the contents of
- * the settings files stored on disk. If there are no pritner specific
- * settings saved for the specified printer, the options string
- * is returned as NULL.
- *
- * Parameters:
- * printer (I) - printer whose options are wanted. If NULL,
- * the default printer is used.
- * printer_optsp (O) - set to point to a printer specific options
- * string or NULL if no printer specific options
- * set for this printer or the printer does not
- * exist.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred. It is considered an error to call this function
- * if the System V spooler is not the currently set spooling system.
- *
- **************************************************************************/
-
- int SLSysVGetPrinterOptions(const char *printer, char **printer_optsp)
- {
- char *def_printer;
-
- /*
- * In case of error make sure sane values are sent back
- */
- *printer_optsp = NULL;
-
- /*
- * Make sure we have the System V spooler set otherwise
- * we return an error indication.
- */
- CHECK_DEF_SPOOLER;
- if (def_sptr->mask != SL_SPOOLER_SYSV)
- RETURN_ERROR(SL_ERR_NO_SYSV);
-
- /*
- * Get the default printer name if no printer specified.
- * Also sanity check the printer name, if specified.
- */
- if (!printer) {
- if (SLGetDefPrinterName(&def_printer) < 0)
- return SL_ERROR;
- printer = def_printer;
- } else if (_SLIsEmpty(printer))
- RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
-
- /*
- * Call the appropriate function
- */
- if (_SLSysVGetPrinterOptions(printer, printer_optsp) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSysVSaveSpoolerOptions
- *
- * Description: Saves the System V spooler specific options.
- *
- * Parameters:
- * spooler_opts (I) - settings to save.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred. It is considered an error to call this function
- * if the System V spooler is not the currently set spooling system.
- *
- **************************************************************************/
-
- int SLSysVSaveSpoolerOptions(SLSysVSpoolerOptionsStruct *spooler_opts)
- {
- /*
- * Make sure we have the System V spooler set otherwise
- * we return an error indication.
- */
- CHECK_DEF_SPOOLER;
- if (def_sptr->mask != SL_SPOOLER_SYSV)
- RETURN_ERROR(SL_ERR_NO_SYSV);
-
- /*
- * Call the appropriate function
- */
- if (_SLSysVSaveSpoolerOptions(spooler_opts) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSysVSavePrinterOptions
- *
- * Description: Saves the System V printer specific option settings.
- *
- * Parameters:
- * printer (I) - printer whose options are to be saved. If NULL,
- * the default printer is used.
- * printer_opts (I) - options to save.
- * location (I) - Save settings for this user (SL_SAVE_USER) or
- * for all users (SL_SAVE_DEFAULT). Note that for
- * default save to work you must be either 'root'
- * or 'lp' according to your current uid.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred. It is considered an error to call this function
- * if the System V spooler is not the currently set spooling system.
- *
- **************************************************************************/
-
- int SLSysVSavePrinterOptions(const char *printer,
- char *printer_opts, int location)
- {
- char *def_printer;
-
- /*
- * Sanity checks location
- */
- if (location != SL_SAVE_USER && location != SL_SAVE_DEFAULT)
- location = SL_SAVE_USER;
-
- /*
- * Make sure we have the System V spooler set otherwise
- * we return an error indication.
- */
- CHECK_DEF_SPOOLER;
- if (def_sptr->mask != SL_SPOOLER_SYSV)
- RETURN_ERROR(SL_ERR_NO_SYSV);
-
- /*
- * Get the default printer name if no printer specified.
- * Also sanity check the printer name, if specified.
- */
- if (!printer) {
- if (SLGetDefPrinterName(&def_printer) < 0)
- return SL_ERROR;
- printer = def_printer;
- } else if (_SLIsEmpty(printer))
- RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
-
- /*
- * Call the appropriate function
- */
- if (_SLSysVSavePrinterOptions(printer, printer_opts, location) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSubmitJob
- *
- * Description: Submits a job for printing. A print job structure pointer
- * is returned that can be used to subsequently cancel or track the
- * status of the job. This pointer is reused by this function so users
- * wishing to preserve the data in the structure should copy the
- * structure.
- *
- * Parameters:
- * filename (I) - file(s) to print. Wildcards acceptable. Multiple
- * filenames should be separated by whitespace.
- * printer (I) - printer on which to print job. If NULL then default
- * printer is used.
- * num_copies (I) - number of copies
- * copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
- * 0 a link is created.
- * mail (I) - Mail flag. If 1 then mail is sent on job print completion.
- * If 0, no mail is sent.
- * title (I) - title to appear on banner page.
- * options (I) - string of spooling system/printer specific options.
- * Set to NULL if none.
- *
- * Return: If no error, a pointer to a print job structure is returned. If
- * the information in this structure is to be maintained and more jobs
- * are to be submitted, this structure should be copied to a user buffer.
- * NULL is returned and SLerrno is set if an error has occurred.
- *
- **************************************************************************/
-
- SLPrintJob* SLSubmitJob(const char *filename, const char *printer,
- int num_copies, int copy, int mail,
- const char *title, const char *options)
- {
- SLJobSourceUnion job_source;
- SLPrintJob *pjob;
-
- /*
- * Perform basic sanity check on the filename
- */
- if (!filename || _SLIsEmpty(filename))
- RETURN_ERROR_PTR(SL_ERR_NO_FILENAME);
-
- /*
- * File out the job source structure
- */
- job_source.type = SL_JOB_FILENAME;
- job_source.filename_job.filename = filename;
-
- /*
- * Call the generic job submittal routine
- */
- pjob = submit_job(&job_source, printer, num_copies, copy, mail, title,
- options);
-
- return pjob;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSubmitJobFd
- *
- * Description: Submits a job for printing. The source for the print job
- * is the specified file descriptor. A print job structure pointer
- * is returned that can be used to subsequently cancel or track the
- * status of the job. This pointer is reused by this function so users
- * wishing to preserve the data in the structure should copy the
- * structure.
- *
- * Parameters:
- * file_desc (I) - File descriptor of a file open for reading.
- * The contents of this file is printed.
- * printer (I) - printer on which to print job. If NULL then default
- * printer is used.
- * num_copies (I) - number of copies
- * copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
- * 0 a link is created.
- * mail (I) - Mail flag. If 1 then mail is sent on job print completion.
- * If 0, no mail is sent.
- * title (I) - title to appear on banner page.
- * options (I) - string of spooling system/printer specific options.
- * Set to NULL if none.
- *
- * Return: If no error, a pointer to a print job structure is returned. If
- * the information in this structure is to be maintained and more jobs
- * are to be submitted, this structure should be copied to a user buffer.
- * NULL is returned and SLerrno is set if an error has occurred.
- *
- **************************************************************************/
-
- SLPrintJob* SLSubmitJobFd(int file_desc, const char *printer,
- int num_copies, int copy, int mail,
- const char *title, const char *options)
- {
- SLJobSourceUnion job_source;
- struct stat sbuf;
-
- /*
- * Perform basic sanity check on the file descriptor
- */
- if (fstat(file_desc, &sbuf) < 0)
- RETURN_ERROR_PTR(SL_ERR_BAD_FD);
-
- /*
- * File out the job source structure
- */
- job_source.type = SL_JOB_FD;
- job_source.fd_job.file_desc = file_desc;
-
- /*
- * Call the generic job submittal routine
- */
- return submit_job(&job_source, printer, num_copies, copy, mail, title,
- options);
- }
-
-
- /**************************************************************************
- *
- * Function: SLSubmitJobBuf
- *
- * Description: Submits a job for printing. The source for the print job
- * is the specified buffer of the specified size (in bytes). A print
- * job structure pointer is returned that can be used to subsequently
- * cancel or track the status of the job. This pointer is reused by
- * this function so users wishing to preserve the data in the structure
- * should copy the structure.
- *
- * Parameters:
- * buffer (I) - buffer whose contents are to be printed.
- * amount (I) - number of bytes in buffer.
- * printer (I) - printer on which to print job. If NULL then default
- * printer is used.
- * num_copies (I) - number of copies
- * copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
- * 0 a link is created.
- * mail (I) - Mail flag. If 1 then mail is sent on job print completion.
- * If 0, no mail is sent.
- * title (I) - title to appear on banner page.
- * options (I) - string of spooling system/printer specific options.
- * Set to NULL if none.
- *
- * Return: If no error, a pointer to a print job structure is returned. If
- * the information in this structure is to be maintained and more jobs
- * are to be submitted, this structure should be copied to a user buffer.
- * NULL is returned and SLerrno is set if an error has occurred.
- *
- **************************************************************************/
-
- SLPrintJob* SLSubmitJobBuf(const void *buffer, size_t amount,
- const char *printer, int num_copies,
- int copy, int mail, const char *title,
- const char *options)
- {
- SLJobSourceUnion job_source;
-
- /*
- * Perform basic sanity check on the file descriptor
- */
- if (!buffer || !amount)
- RETURN_ERROR_PTR(SL_ERR_BAD_BUF);
-
- /*
- * File out the job source structure
- */
- job_source.type = SL_JOB_BUF;
- job_source.buf_job.buffer = buffer;
- job_source.buf_job.amount = amount;
-
- /*
- * Call the generic job submittal routine
- */
- return submit_job(&job_source, printer, num_copies, copy, mail, title,
- options);
- }
-
-
- /**************************************************************************
- *
- * Function: SLSubmitJobSimple
- *
- * Description: Submits a job for printing. This function provides a
- * simple job submittal interface for users who wish to accept
- * all defaults. The default printer with the default options
- * are used to print the job.
- *
- * Parameters:
- * filename (I) - file(s) to print. Wildcards acceptable. Multiple
- * filenames should be separated by whitespace.
- *
- * Return: If no error, a pointer to a print job structure is returned. If
- * the information in this structure is to be maintained and more jobs
- * are to be submitted, this structure should be copied to a user buffer.
- * NULL is returned and SLerrno is set if an error has occurred.
- *
- **************************************************************************/
-
- SLPrintJob* SLSubmitJobSimple(const char *filename)
- {
- /*
- * Simply call SLSubmit Job with fields filled in
- */
- return SLSubmitJob(filename, NULL, 1, 0, 0, NULL, NULL);
- }
-
-
- /**************************************************************************
- *
- * Function: SLCancelJob
- *
- * Description: Makes a request to the specified spooling system to cancel
- * the specified job. The following notes apply:
- *
- * 1. No confirmation that the job was found and canceled is
- * provided.
- *
- * 2. If spooler is SL_SPOOLER_NONE, the current spooling system
- * will be used. If a spooler is specified, the job will be
- * canceled on that spooling system, but the specified spooling
- * system will not become the default spooling system.
- *
- * 3. For System V print jobs the printer parameter is ignored and
- * may be set to NULL. This is because the printer for the job
- * is extracted from the job_id.
- *
- * 4. For BSD print jobs if the printer parameter is NULL, the current
- * default printer is assumed.
- *
- * Parameters:
- * job_id (I) - job ID(s) of the print jobs to be canceled. Multiple
- * IDs should be separated by whitepsace.
- * spooler (I) - print spooler to which job was submitted.
- * printer (I) - printer to which job was submitted.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred.
- *
- **************************************************************************/
-
- int SLCancelJob(const char *job_id, unsigned int spooler, const char *printer)
- {
- register SLSpoolerStruct *sptr;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Perform basic sanity checks on parameters
- */
- if (!job_id || _SLIsEmpty(job_id))
- RETURN_ERROR(SL_ERR_NO_JOBID);
-
- /*
- * If no spooler specified use the default spooler's
- * function. If a spooler is specified, make sure that
- * it is valid and call that spooler's cancel function
- */
- if (spooler == SL_SPOOLER_NONE)
- sptr = def_sptr;
- else if (spooler & avail_spoolers)
- for (sptr = pos_spooler_list; !(spooler & sptr->mask); sptr++)
- ;
- else
- RETURN_ERROR(SL_ERR_SPOOLER_UNKNOWN);
-
- if (sptr->cancel_job_func(job_id, printer) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLGetSpoolerState
- *
- * Description: Returns the state of the specified spooling function.
- *
- * Parameters:
- * printer (I) - printer whose spooler state to query. If NULL,
- * the default printer is used.
- * function (I) - spooling function whose state to query (one of
- * SL_PRINTING or SL_QUEUEING).
- * statep (O) - state of the spooling function (one of SL_ENABLED or
- * SL_DISABLED).
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred.
- *
- **************************************************************************/
-
- int SLGetSpoolerState(const char *printer, int function, int *statep)
- {
- char *def_printer;
-
- /*
- * In case of error make sure sane values are sent back
- */
- *statep = SL_DISABLED;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Perform basic sanity checks on the parameters
- */
- if (function != SL_PRINTING && function != SL_QUEUEING)
- RETURN_ERROR(SL_ERR_BAD_FUNCTION);
-
- /*
- * Get the default printer name if no printer specified
- * and do some sanity checking if a printer was specified.
- */
- if (!printer) {
- if (SLGetDefPrinterName(&def_printer) < 0)
- return SL_ERROR;
- printer = def_printer;
- } else if (_SLIsEmpty(printer))
- RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->get_spooler_state_func(printer, function, statep) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSetSpoolerState
- *
- * Description: Sets the state of the specified spooling function.
- * You must have an euid of root to execute this function.
- *
- * Parameters:
- * printer (I) - printer whose spooler state to set. If NULL,
- * the default printer is used.
- * function (I) - spooling function whose state to set (one of
- * SL_PRINTING or SL_QUEUEING).
- * state (I) - state to set for the spooling function (one of
- * SL_ENABLED or SL_DISABLED).
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred.
- *
- **************************************************************************/
-
- int SLSetSpoolerState(const char *printer, int function, int state)
- {
- char *def_printer;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Perform basic sanity checks on the parameters
- */
- if (function != SL_PRINTING && function != SL_QUEUEING)
- RETURN_ERROR(SL_ERR_BAD_FUNCTION);
- if (state != SL_ENABLED && state != SL_DISABLED)
- RETURN_ERROR(SL_ERR_BAD_STATE);
-
- /*
- * Get the default printer name if no printer specified
- * and do sanity checking if a printer was specified.
- */
- if (!printer) {
- if (SLGetDefPrinterName(&def_printer) < 0)
- return SL_ERROR;
- printer = def_printer;
- } else if (_SLIsEmpty(printer))
- RETURN_ERROR(SL_ERR_BAD_PRINTER_NAME);
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->set_spooler_state_func(printer, function, state) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLGetQueue
- *
- * Description: Returns the job queue for the specified printer. Note that
- * this function requires a printer structure passed as opposed to a
- * printer name. This is because the printer structure contains info
- * regarding whether the printer is remote and if so, where it is
- * located. Note that the any old pointer to the queue will be invalid
- * after this call. To save a previous queue the queue structures
- * must be copied.
- *
- * Parameters:
- * printer_info (I) - printer structure. Cannot be NULL.
- * queue_type (I) - type of queue to obtain (ie. local, remote or
- * merged. Ignored for local printers and for
- * BSD spooler.
- * queuep (O) - print queue entries.
- * num_queuep (O) - number of entries in the queue.
- *
- * Return: 0 is execution succeeded. -1 and SLerrno is set if an execution
- * error has occurred.
- *
- **************************************************************************/
-
- int SLGetQueue(const SLPrinterStruct *printer_info, int queue_type,
- SLQueueStruct *queuep[], int *num_queuep)
- {
- /*
- * In case no spooler make sure sane values are sent back
- */
- *queuep = NULL;
- *num_queuep = 0;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER;
-
- /*
- * Perform basic sanity checks on the parameters
- */
- if (!printer_info)
- RETURN_ERROR(SL_ERR_BAD_PRINTER_STRUCT);
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->get_queue_func(printer_info, queue_type,
- queuep, num_queuep) < 0)
- return SL_ERROR;
-
- return SL_NOERROR;
- }
-
-
- /**************************************************************************
- *
- * Function: SLGetSpoolerError
- *
- * Description: If SLerrno == SL_ERR_SPOOLER_ERROR this function can
- * be called to get the spooler error message(s), if any. This
- * function first checks SLerrno to verify that it is set to
- * SL_ERR_SPOOLER_ERROR. If it is not, then the function sets
- * noutp to 0 and returns. The function returns a list of strings
- * which comprise the output from the spooling system and a count
- * of the number of lines of output.
- *
- * Parameters:
- * out_bufp (O) - list of strings comprising the output from the
- * spooling system.
- * noutp (O) - number of lines of output.
- *
- * Return: Exit status of spooler command that caused the error.
- *
- **************************************************************************/
-
- int SLGetSpoolerError(char **out_bufp[], int *noutp)
- {
- /*
- * Make sure that last error was a spooler error
- */
- if (SLerrno != SL_ERR_SPOOLER_ERROR) {
- *noutp = 0;
- return 0;
- }
-
- /*
- * Set parameters to the buffer globals
- */
- *out_bufp = _SLspooler_out_buf;
- *noutp = _SLspooler_nout;
-
- /*
- * Return spooler command exit code
- */
- return _SLspooler_exit;
- }
-
-
- #ifdef _SL_FASTPATH
- /**************************************************************************
- *
- * Function: SLBeginFastJob
- *
- * Description:
- * Submit a job to the fast path through the spooling system.
- * The idea is that for enormous print jobs, it is very wasteful
- * to write all the data to disk, and then have it copied around
- * the spooling system, and finally piped to the printer driver.
- * Instead, this function in cooperation with the model file for
- * the printer sets up a socket so the application can
- * communicate directly with the scanner driver, or at least to
- * the filters that must be invoked to preprocess the data.
- *
- * Parameters:
- * printer Printer to send data to
- * ncopies Number of copies to print
- * mail Mail on completion
- * title title of job
- * options printer specific options
- *
- * Return: Pointer to a SLFastPrintJob if successful, NULL if error
- *
- **************************************************************************/
-
- SLFastPrintJob* SLBeginFastJob(const char *printer, int ncopies,
- int mail, const char *title, const char *options)
- {
- int sock;
- FASTHEADER header;
- SLFastPrintJob *fj = 0;
- SLPrintJob *job;
-
- if (!SLSupportsFastJob(printer)) {
- RETURN_ERROR_PTR(SL_ERR_NO_FAST_JOB);
- }
-
- if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- RETURN_ERROR_PTR(SL_ERR_BAD_SOCKET);
- }
-
- header.magic = FASTMAGIC;
- header.ftype = 0;
- header.addrlen = sizeof(header.addr.in);
-
- if (listen(sock, 1) < 0
- || getsockname(sock, &header.addr.in, &header.addrlen) < 0) {
- if (SLdebug) {
- perror("socket");
- }
- (void)close(sock);
- RETURN_ERROR_PTR(SL_ERR_BAD_SOCKET);
- }
-
- job = SLSubmitJobBuf(&header, sizeof(header), printer, ncopies,
- 1, mail, title, options);
-
- if (job) {
- fj = malloc(sizeof(*fj));
- fj->job = malloc(sizeof(fj->job));
- bcopy(job, fj->job, sizeof(fj->job));
- fj->sock = sock;
- } else {
- (void)close(sock);
- }
-
- return fj;
- }
-
-
- /**************************************************************************
- *
- * Function: SLCancelFastJob
- *
- * Description:
- * Interrupt a fast print job.
- *
- * Parameters:
- * fj The fast job to interrupt
- *
- * Return: 0 if successful, -1 if error
- *
- **************************************************************************/
-
- int SLCancelFastJob(SLFastPrintJob *fj)
- {
- (void)SLCancelJob(fj->job->job_id, fj->job->spooler, fj->job->printer);
- (void)SLEndFastJob(fj);
- return 0;
- }
-
-
- /**************************************************************************
- *
- * Function: SLEndFastJob
- *
- * Description:
- * Terminate a fast print job normally. To be called when all
- * data has been sent. Frees resources associated with a fast
- * print job.
- *
- * Parameters:
- * fj The fast job to terminate
- *
- * Return: 0 if successful, -1 if error
- *
- **************************************************************************/
-
- int SLEndFastJob(SLFastPrintJob *fj)
- {
- (void)close(fj->sock);
- free(fj->job);
- free(fj);
- return 0;
- }
-
-
- /**************************************************************************
- *
- * Function: SLSupportsFastJob
- *
- * Description:
- * Find out whether a printer supports fast print jobs
- *
- * Parameters:
- * printer printer to find out if supports fast jobs
- *
- * Return: non-zero if fast job supported, 0 otherwise
- *
- **************************************************************************/
-
- int
- SLSupportsFastJob(const char *printer)
- {
- CHECK_DEF_SPOOLER;
- return def_sptr->supports_fast_job(printer);
- }
- #endif /* _SL_FASTPATH */
-
-
- /*
- ==========================================================================
- LOCAL FUNCTIONS
- ==========================================================================
- */
-
-
- /**************************************************************************
- *
- * Function: find_spoolers
- *
- * Description: Supervises the determination of which print spoolers are
- * available. This is based on a determination of whether the spooler's
- * scheduler is running.
- *
- * Parameters:
- * spoolersp (O) - bit mask of available spoolers
- *
- * Return: 0 if success, -1 if error. SLerrno is not set.
- *
- **************************************************************************/
-
- static int find_spoolers(unsigned int *spoolersp)
- {
- register SLSpoolerStruct *sptr;
-
- /*
- * Based on the list of possible spoolers see which one's
- * demon(s) is around.
- */
- *spoolersp = SL_SPOOLER_NONE;
- for (sptr = pos_spooler_list; sptr->find_spooler_func; sptr++) {
- if (sptr->find_spooler_func())
- *spoolersp |= sptr->mask;
- }
-
- return 0;
- }
-
- /**************************************************************************
- *
- * Function: init_job
- *
- * Description: Deallocates the storage associated with the members of
- * a printer job structure and initializes other fields.
- *
- * Parameters:
- * job (I) - printer job whose storage is to be deallocated.
- *
- * Return: none
- *
- **************************************************************************/
-
- static void init_job(SLPrintJob *job)
- {
- job->spooler = SL_SPOOLER_NONE;
- if (job->printer) {
- free((char*)job->printer);
- job->printer = NULL;
- }
- if (job->filename) {
- free((char*)job->filename);
- job->filename = NULL;
- }
- if (job->username) {
- free((char*)job->username);
- job->username = NULL;
- }
- if (job->job_id) {
- free((char*)job->job_id);
- job->job_id = NULL;
- }
- }
-
-
- /**************************************************************************
- *
- * Function: submit_job
- *
- * Description: Submits a job for printing. A print job structure pointer
- * is returned that can be used to subsequently cancel or track the
- * status of the job. This pointer is reused by this function so users
- * wishing to preserve the data in the structure should copy the
- * structure.
- *
- * Parameters:
- * job_source (I) - the job to print. This is a pointer to the union of
- * structures indicating the job source. The first field
- * describes the job type (eg. filename, fd, etc.).
- * printer (I) - printer on which to print job. If NULL then default
- * printer is used.
- * num_copies (I) - number of copies
- * copy (I) - Copy flag. If 1 then file is copied to spooling dir. If
- * 0 a link is created.
- * mail (I) - Mail flag. If 1 then mail is sent on job print completion.
- * If 0, no mail is sent.
- * title (I) - title to appear on banner page.
- * options (I) - string of spooling system/printer specific options.
- * Set to NULL if none.
- *
- * Return: If no error, a pointer to a print job structure is returned. If
- * the information in this structure is to be maintained and more jobs
- * are to be submitted, this structure should be copied to a user buffer.
- * NULL is returned and SLerrno is set if an error has occurred.
- *
- **************************************************************************/
-
- static SLPrintJob* submit_job(SLJobSourceUnion *job_source,
- const char *printer, int num_copies, int copy,
- int mail, const char *title, const char *options)
- {
- char *job_id;
- char *def_printer;
- time_t jtime;
- struct tm *jtm;
-
- /*
- * Make sure we have a valid spooler selected
- */
- CHECK_DEF_SPOOLER_PTR;
-
- /*
- * Perform basic sanity checks on the parameters
- */
- if (num_copies < 1)
- RETURN_ERROR_PTR(SL_ERR_NUM_COPIES);
- if (copy != 0 && copy != 1)
- RETURN_ERROR_PTR(SL_ERR_JOB_COPY);
- if (mail != 0 && mail != 1)
- RETURN_ERROR_PTR(SL_ERR_MAIL);
-
- /*
- * Initialize the job structure
- */
- init_job(&print_job);
-
- /*
- * Get the default printer name if no printer specified
- */
- if (!printer) {
- if (SLGetDefPrinterName(&def_printer) < 0)
- return NULL;
- printer = def_printer;
- } else if (_SLIsEmpty(printer))
- RETURN_ERROR_PTR(SL_ERR_BAD_PRINTER_NAME);
-
- /*
- * Call the appropriate function
- */
- if (def_sptr->submit_job_func(job_source, printer, num_copies,
- copy, mail, title, options, &job_id) < 0)
- return NULL;
-
- /*
- * Fill out the info structure
- */
- print_job.spooler = def_spooler;
- print_job.printer = strdup(SL_CHAR_CAST(printer));
- if (job_source->type == SL_JOB_FILENAME)
- print_job.filename =
- strdup(SL_CHAR_CAST(job_source->filename_job.filename));
- else
- print_job.filename = strdup("Standard Input");
- print_job.username = strdup(def_sptr->find_username());
- print_job.job_id = (job_id) ? strdup(job_id): NULL;
-
- /*
- * Put in the time stamp. We zero out the seconds because lpstat
- * tends to report job queue time stamps only to the minute
- */
- jtime = time((time_t*)NULL);
- jtm = localtime(&jtime);
- jtm->tm_sec = 0;
- print_job.time_stamp = mktime(jtm);
-
- return &print_job;
- }
-
-
- /**************************************************************************
- *
- * Function: sort_plist
- *
- * Description: Performs a Shell sort on the printer list to sort the list
- * case independently in alphabetical order by local name. The Shell
- * sort is used because we will ussually be dealing with very few
- * items in the list.
- *
- * Parameters:
- * plist (I,O) - printer list to be sorted
- * num (I) - number of printers in the list
- *
- * Return: none
- *
- **************************************************************************/
-
- static void sort_plist(SLPrinterStruct *plist, register int num)
- {
- register int i, j, k, s, *ap;
- static int a[] = { 9, 5, 3, 2, 1, 0};
- SLPrinterStruct x;
-
- if (!plist || num < 2)
- return;
-
- for (ap = a; *ap; ap++) {
- k = *ap;
- s = -k;
- for (i = k; i < num; i++) {
- x = plist[i];
- j = i - k;
- if (!s) {
- s = -k;
- plist[++s] = x;
- }
- while (j >= 0 && j < num &&
- strcasecmp(x.local_name, plist[j].local_name) < 0) {
- plist[j + k] = plist[j];
- j -= k;
- }
- plist[j + k] = x;
- }
- }
- }
-